<template>
  <view class="player-container">
    <!-- 专辑封面区域 -->
    <view class="cover-section">
      <view class="album-cover">
        <view class="halo"></view>
        <image v-if="playSong && playSong.cover" :src="playSong.cover" class="cover-img" mode="aspectFill" />
      </view>
    </view>

    <!-- 歌曲信息区域 -->
    <view class="song-info">
      <text class="song-name">{{ playSong ? playSong.title : '' }}</text>
    </view>

    <!-- 歌词显示区域 -->
    <scroll-view class="lyrics-container" scroll-y :scroll-into-view="lyricScrollId" scroll-with-animation>
      <view class="lyrics-content">
        <view v-if="playSong && playSong.lyrics && playSong.lyrics.parsed"
          v-for="(line, index) in playSong.lyrics.parsed" :key="'lyric-' + index"
          :id="'lyric-' + index"
          :class="['lyric-line', { active: currentLine === index }]"
          @click="seekLyric(line)">
          {{ line.text }}
        </view>
        <view v-else :key="'no-lyric'" class="lyric-line">暂无歌词</view>
      </view>
    </scroll-view>

    <!-- 悬浮按钮 -->
    <view class="playlist-fab" @click="showPlaylist = true">
      <text class="fab-icon">🎵</text>
    </view>

    <!-- 遮罩和弹窗 -->
    <view v-if="showPlaylist" class="playlist-mask" @click="showPlaylist = false"></view>
    <view :class="['playlist-popup', { show: showPlaylist }]">
      <view class="popup-header">
        <text class="popup-title">待播放列表</text>
        <text class="popup-close" @click="showPlaylist = false">✕</text>
      </view>
      <scroll-view scroll-y class="popup-list">
        <view v-for="(song, idx) in playList" :key="idx"
              :class="['popup-item', { active: idx === currentIndex }]"
              @click="switchSong(idx); showPlaylist = false">
          <text class="popup-song">{{ song.title }}</text>
          <text class="popup-artist">{{ song.artist }}</text>
        </view>
      </scroll-view>
    </view>

    <!-- 播放控制栏 -->
    <view class="control-bar">
      <view class="progress-bar" @click="handleProgressClick">
        <view class="progress" :style="{ width: progress + '%' }"></view>
      </view>
      <view class="controls">
        <view class="control-btn play-pause" :class="{ playing: isPlaying }" @click="togglePlay"></view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from 'vue'
import { onLoad } from '@dcloudio/uni-app'

const playList = ref([])
const playSong = ref(null)
const isPlaying = ref(false)
const progress = ref(0)
const currentLine = ref(0)
const audioCtx = ref(null)
const duration = ref(0)
const currentTime = ref(0)
const currentIndex = ref(0)
const showPlaylist = ref(false)
const lyricScrollId = ref('')

// 歌词解析辅助
function parseLyrics(lyricsObj) {
  if (!lyricsObj || !Array.isArray(lyricsObj.parsed)) return []
  return lyricsObj.parsed.map(item => ({ time: item.time, text: item.text }))
}

onLoad(() => {
  const song = uni.getStorageSync('current_play_song')
  const list = uni.getStorageSync('current_play_list')
  if (Array.isArray(list) && list.length > 0) {
    playList.value = list
    // 定位当前播放索引
    const idx = list.findIndex(item => item.audio_url === song.audio_url)
    currentIndex.value = idx >= 0 ? idx : 0
    playSong.value = playList.value[currentIndex.value]
  } else if (song && song.audio_url) {
    playSong.value = song
    playList.value = [song]
    currentIndex.value = 0
  } else {
    uni.showToast({ title: '未找到歌曲数据', icon: 'none' })
  }
  initAudio()
})

function initAudio() {
  if (playSong.value && playSong.value.audio_url) {
    if (audioCtx.value) audioCtx.value.destroy()
    audioCtx.value = uni.createInnerAudioContext()
    audioCtx.value.src = playSong.value.audio_url
    audioCtx.value.autoplay = false
    audioCtx.value.onPlay(() => { isPlaying.value = true })
    audioCtx.value.onPause(() => { isPlaying.value = false })
    audioCtx.value.onStop(() => { isPlaying.value = false })
    audioCtx.value.onEnded(() => { isPlaying.value = false; progress.value = 100 })
    audioCtx.value.onTimeUpdate(() => {
      currentTime.value = audioCtx.value.currentTime
      duration.value = audioCtx.value.duration
      progress.value = duration.value ? (currentTime.value / duration.value) * 100 : 0
      // 歌词高亮
      if (playSong.value.lyrics && playSong.value.lyrics.parsed) {
        for (let i = playSong.value.lyrics.parsed.length - 1; i >= 0; i--) {
          if (currentTime.value >= playSong.value.lyrics.parsed[i].time) {
            currentLine.value = i
            break
          }
        }
      }
    })
  }
}

const togglePlay = () => {
  if (audioCtx.value) {
    if (isPlaying.value) {
      audioCtx.value.pause()
    } else {
      audioCtx.value.play()
    }
  }
}

const handleProgressClick = (e) => {
  if (audioCtx.value && duration.value) {
    const percent = e.detail.x / uni.upx2px(uni.getSystemInfoSync().windowWidth * 0.9)
    const seekTime = percent * duration.value
    audioCtx.value.seek(seekTime)
    progress.value = percent * 100
  }
}

const switchSong = (idx) => {
  if (idx !== currentIndex.value) {
    currentIndex.value = idx
    playSong.value = playList.value[idx]
    progress.value = 0
    currentLine.value = 0
    initAudio()
    setTimeout(() => {
      audioCtx.value.play()
    }, 200)
  }
}

const seekLyric = (line) => {
  if (audioCtx.value && line && typeof line.time === 'number') {
    audioCtx.value.seek(line.time)
  }
}

// 歌词高亮自动滚动
watch(currentLine, (val) => {
  lyricScrollId.value = 'lyric-' + val
  nextTick(() => {})
})
</script>

<style lang="scss" scoped>
.player-container {
  min-height: 100vh;
  background: radial-gradient(circle at center, #006633, #66FF99);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 40rpx;
}

.cover-section {
  margin-top: 60rpx;
  position: relative;
}

.album-cover {
  width: 80vw;
  aspect-ratio: 1;
  background-color: #FFFFFF;
  border-radius: 50%;
  position: relative;
}

.halo {
  position: absolute;
  top: -20rpx;
  left: -20rpx;
  right: -20rpx;
  bottom: -20rpx;
  border-radius: 50%;
  background-color: #66FF99;
  opacity: 0.5;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { transform: scale(1); opacity: 0.5; }
  50% { transform: scale(1.1); opacity: 0.3; }
  100% { transform: scale(1); opacity: 0.5; }
}

.song-info {
  text-align: center;
  margin-top: 40rpx;
}

.song-name {
  font-size: 2rem;
  color: #FFFFFF;
  font-weight: bold;
  display: block;
  margin-bottom: 20rpx;
}

.artist, .album {
  font-size: 1.2rem;
  color: #CCCCCC;
  display: block;
  margin-bottom: 10rpx;
}

.lyrics-container {
  width: 90%;
  height: 30vh;
  margin-top: 40rpx;
  background-color: rgba(255, 255, 255, 0.3);
  border-radius: 20rpx;
  padding: 20rpx;
}

.lyrics-content {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.lyric-line {
  font-size: 1.1rem;
  color: #006633;
  margin: 20rpx 0;
  transition: all 0.3s;
}

.lyric-line.active {
  color: #FFFFFF;
  font-size: 1.2rem;
  font-weight: bold;
}

// 悬浮按钮
.playlist-fab {
  position: fixed;
  right: 36rpx;
  bottom: 140rpx;
  width: 60rpx;
  height: 60rpx;
  background: linear-gradient(135deg, #66FF99 60%, #006633 100%);
  border-radius: 50%;
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1002;
  cursor: pointer;
  transition: box-shadow 0.2s;
  &:active {
    box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  }
}
.fab-icon {
  font-size: 1.5rem;
  color: #fff;
}

// 遮罩
.playlist-mask {
  position: fixed;
  left: 0; top: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,0.25);
  z-index: 1001;
}

// 弹窗
.playlist-popup {
  position: fixed;
  left: 0; right: 0; bottom: -60vh;
  height: 52vh;
  background: rgba(255,255,255,0.92);
  border-top-left-radius: 32rpx;
  border-top-right-radius: 32rpx;
  box-shadow: 0 -8px 32px rgba(0,0,0,0.12);
  z-index: 1003;
  transition: bottom 0.32s cubic-bezier(.4,1.6,.6,1);
  display: flex;
  flex-direction: column;
  &.show {
    bottom: 0;
  }
}
.popup-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24rpx 32rpx 12rpx 32rpx;
}
.popup-title {
  font-size: 1.2rem;
  color: #006633;
  font-weight: bold;
}
.popup-close {
  font-size: 1.5rem;
  color: #999;
  cursor: pointer;
}
.popup-list {
  flex: 1;
  overflow-y: auto;
  padding: 0 24rpx 24rpx 24rpx;
}
.popup-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: 16rpx 0 10rpx 0;
  border-bottom: 1px solid #e0e0e0;
  font-size: 1.1rem;
  color: #006633;
  border-radius: 12rpx;
  transition: background 0.2s, color 0.2s;
  &:last-child { border-bottom: none; }
  &.active {
    background: linear-gradient(90deg, #66FF99 0%, #e0ffe0 100%);
    color: #fff;
    font-weight: bold;
  }
}
.popup-song {
  font-weight: 600;
  max-width: 90vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 1.08rem;
}
.popup-artist {
  font-size: 0.92rem;
  color: #009966;
  margin-top: 2rpx;
  max-width: 90vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: 0.7;
}

.control-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #FFFFFF;
  padding: 20rpx;
  box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
}

.progress-bar {
  width: 90%;
  height: 10rpx;
  background-color: #F0F0F0;
  border-radius: 5rpx;
  margin: 0 auto 20rpx;
  position: relative;
}

.progress {
  position: absolute;
  height: 100%;
  background-color: #006633;
  border-radius: 5rpx;
}

.controls {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.control-btn {
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  background-color: #006633;
}

.play-pause {
  width: 100rpx;
  height: 100rpx;
}

.play-pause.playing {
  background-color: #FF0000;
}

.cover-img {
  position: absolute;
  left: 0; top: 0; right: 0; bottom: 0;
  width: 100%; height: 100%; border-radius: 50%;
  z-index: 2;
}
</style>
